﻿using System;
using System.Collections.Generic;
using Mbs.ComponentModel.Container.Activation;
using Mbs.ComponentModel.Container.Context;
using Mbs.ComponentModel.Container.Metadata;

namespace Mbs.ComponentModel.Container.Lifestyle
{
    [Serializable]
    public class GenericLifestyleManager<TLifestyleManager> : ILifestyleManager where TLifestyleManager : ILifestyleManager, new()
    {
        protected IDictionary<int, TLifestyleManager> cache = new Dictionary<int, TLifestyleManager>();

        #region ILifestyleManager Members

        public IMicroKernel Kernel { get; private set; }
        public IActivator Activator { get; private set; }
        public IComponentInfo Info { get; private set; }
        public Action<IComponentInfo, object> OnDestroyed { get; private set; }

        public virtual void Init(IActivator activator, IMicroKernel kernel, IComponentInfo info, Action<IComponentInfo, object> onDestroyed)
        {
            this.Activator = activator;
            this.Kernel = kernel;
            this.Info = info;
            OnDestroyed = onDestroyed;
        }

        public virtual object Get(ICreateContext ctx)
        {
            int key = 123;
            foreach (var item in ctx.GenericParameters)
                key = key ^ item.TypeHandle.Value.GetHashCode();

            if (!cache.ContainsKey(key))
            {
                var lifestyleMgr = new TLifestyleManager();
                lifestyleMgr.Init(Activator, ctx.Kernel, ctx.Component, OnDestroyed);
                cache[key] = lifestyleMgr;
            }

            return cache[key].Get(ctx);
        }

        public virtual bool Release(object instance)
        {
            return false;
        }

        public virtual bool Release()
        {
            return false;
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            foreach (var item in cache.Values)
                item.Dispose();
        }

        #endregion
    }
}
